package server;

import communication.Connection;
import communication.ConnectionException;
import communication.ServerSecureConnectionManager;
import constans.WarningConstantes;
import java.io.File;
import java.sql.SQLException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import security.CipherFile;
import security.SealedObj;
import security.Signature;
import database.Database;
import database.DatabaseOperationsCapsules;
import database.DatabaseOperationsCapsulesTemporary;
import database.DatabaseOperationsIdentifiers;

public class RecuperationManager extends Process {



	private Recovery recovery;
	private File folderCapsuleTemporary;


	public RecuperationManager(Database database, Signature signature,SealedObj sealdObj,
            CipherFile cipher, int portServer,int maxUsers, File folderCapsule, File folderCapsuleTemporary,
            Logger logger)
	throws SQLException {
		this.authenticator = new Authenticator(new DatabaseOperationsIdentifiers(database.getConnection()),
                sealdObj, signature);
		this.recovery  = new Recovery( new DatabaseOperationsCapsulesTemporary(database.getConnection()),
                new DatabaseOperationsCapsules(database.getConnection()),folderCapsuleTemporary);
		this.verifier = new Verifier(new DatabaseOperationsCapsules(database.getConnection()));				
		this.updater = new Updater(new DatabaseOperationsIdentifiers(database.getConnection()),
                new DatabaseOperationsCapsulesTemporary(database.getConnection()));
		this.portServer = portServer;
        this.maxUsers = maxUsers;
		this.folderCapsuleTemporary = folderCapsuleTemporary;
        this.isStable = new AtomicBoolean(true);
		this.logger = logger;
	}


	public void run(){	
		 Connection connection = null;
      


     try {

            serverSecureConnectionManager = new ServerSecureConnectionManager(portServer);

            while (isStable.get()) {
                try {

                    logger.log(Level.INFO, "Waiting....");
                    connection = serverSecureConnectionManager.acceptConnection();

                    if(authenticator.getNumberIdentifiers() < maxUsers){
                       new ThreadRecovery(connection, authenticator, verifier, recovery, updater, folderCapsuleTemporary, isStable, logger).start();
                    }
                    else{
                           logger.log(Level.WARNING,"Warning code("+WarningConstantes.WARNING_MAX_USERS+"): Too many users");
                           closeConnection(connection);
                    }
                } catch (ConnectionException e) {
                    logger.log(Level.WARNING, "Warning code("+WarningConstantes.WARNING_CONNECTION+"): "+e.getMessage());
                    closeConnection(connection);
                }
            }
        } catch (ConnectionException e) {
            logger.log(Level.SEVERE, e.getMessage());
        }
    }


    public void stopRun() {
        if (serverSecureConnectionManager != null) {
            try {
                serverSecureConnectionManager.close();
            } catch (ConnectionException ex) {}
        }
    }


    private void closeConnection(Connection connection){
          if (connection != null) {
                        try {
                            connection.close();
                        } catch (ConnectionException ex) {}
                        connection = null;
           }
    }

     
    
}